package com.yl.nettylearning.netty.rpc.netty;

import io.netty.channel.ChannelHandlerContext;
import io.netty.channel.ChannelInboundHandlerAdapter;

import java.util.concurrent.Callable;

/**
 * @author yangl
 * 调用的顺序
 * channelActive----setParam----call----channelRead----call
 * 如果出了异常，才调用exception
 */
public class NettyClientHandler extends ChannelInboundHandlerAdapter implements Callable {

    private ChannelHandlerContext context;
    private String result;  //返回的结果
    private String param;   //传入的参数


    @Override
    public void channelActive(ChannelHandlerContext ctx) throws Exception {
        System.out.println("客户端 channelActive被调用。。。。");
        context = ctx;
    }

    /**
     * 收到服务的数据后，调用该方法
     * @param ctx
     * @param msg
     * @throws Exception
     */
    @Override
    public synchronized void channelRead(ChannelHandlerContext ctx, Object msg) throws Exception {
        System.out.println("客户端channelRead方法被调用。。。");
        result = msg.toString();
        //唤醒等待的线程
        notify();
    }

    @Override
    public void exceptionCaught(ChannelHandlerContext ctx, Throwable cause) throws Exception {
        System.out.println(cause.getMessage());
        ctx.close();
    }

    /**
     * 被代理对象调用，发送数据给服务器
     * 发送完了之后->wait->等待被唤起(channelRead)->返回结果
     * @return
     * @throws Exception
     */
    @Override
    public synchronized Object call() throws Exception {
        System.out.println("call");
        context.writeAndFlush(param);
        //发送完了数据之后，等待
        wait();
        //等待channelRead 方法获取到服务器的结果后，唤起
        //服务方返回的结果
        System.out.println("返回结果" + result);
        return result;
    }

    /**
     *设置参数
     * @param param
     */
    void setParam(String param){
        System.out.println(param);
        this.param = param;
    }
}
